{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "gG-V_KZzqSSr"
   },
   "source": [
    "# Tutorial Part 16: Conditional Generative Adversarial Network\n",
    "\n",
    "A Generative Adversarial Network (GAN) is a type of generative model.  It consists of two parts called the \"generator\" and the \"discriminator\".  The generator takes random values as input and transforms them into an output that (hopefully) resembles the training data.  The discriminator takes a set of samples as input and tries to distinguish the real training samples from the ones created by the generator.  Both of them are trained together.  The discriminator tries to get better and better at telling real from false data, while the generator tries to get better and better at fooling the discriminator.\n",
    "\n",
    "A Conditional GAN (CGAN) allows additional inputs to the generator and discriminator that their output is conditioned on.  For example, this might be a class label, and the GAN tries to learn how the data distribution varies between classes.\n",
    "\n",
    "## Colab\n",
    "\n",
    "This tutorial and the rest in this sequence are designed to be done in Google colab. If you'd like to open this notebook in colab, you can use the following link.\n",
    "\n",
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/deepchem/deepchem/blob/master/examples/tutorials/16_Conditional_Generative_Adversarial_Networks.ipynb)\n",
    "\n",
    "## Setup\n",
    "\n",
    "To run DeepChem within Colab, you'll need to run the following cell of installation commands. This will take about 5 minutes to run to completion and install your environment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 170
    },
    "colab_type": "code",
    "id": "gXeKc6O9qSSw",
    "outputId": "9872d3b7-bf6d-4977-d064-ca122f539751"
   },
   "outputs": [],
   "source": [
    "!curl -Lo conda_installer.py https://raw.githubusercontent.com/deepchem/deepchem/master/scripts/colab_install.py\n",
    "import conda_installer\n",
    "conda_installer.install()\n",
    "!/root/miniconda/bin/conda info -e"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 188
    },
    "colab_type": "code",
    "id": "xDBRoR3pFeGs",
    "outputId": "d336d18f-703d-4268-c5eb-e39d6ce86148"
   },
   "outputs": [],
   "source": [
    "!pip install --pre deepchem\n",
    "import deepchem\n",
    "deepchem.__version__"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Vr4T07_aqSS_"
   },
   "source": [
    "For this example, we will create a data distribution consisting of a set of ellipses in 2D, each with a random position, shape, and orientation.  Each class corresponds to a different ellipse.  Let's randomly generate the ellipses.  For each one we select a random center position, X and Y size, and rotation angle.  We then create a transformation matrix that maps the unit circle to the ellipse."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "IdfLLsjGqSTC"
   },
   "outputs": [],
   "source": [
    "import deepchem as dc\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "\n",
    "n_classes = 4\n",
    "class_centers = np.random.uniform(-4, 4, (n_classes, 2))\n",
    "class_transforms = []\n",
    "for i in range(n_classes):\n",
    "    xscale = np.random.uniform(0.5, 2)\n",
    "    yscale = np.random.uniform(0.5, 2)\n",
    "    angle = np.random.uniform(0, np.pi)\n",
    "    m = [[xscale*np.cos(angle), -yscale*np.sin(angle)],\n",
    "         [xscale*np.sin(angle), yscale*np.cos(angle)]]\n",
    "    class_transforms.append(m)\n",
    "class_transforms = np.array(class_transforms)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "xPml_fFGqSTK"
   },
   "source": [
    "This function generates random data from the distribution.  For each point it chooses a random class, then a random position in that class' ellipse."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "ksP0E2KHqSTM"
   },
   "outputs": [],
   "source": [
    "def generate_data(n_points):\n",
    "    classes = np.random.randint(n_classes, size=n_points)\n",
    "    r = np.random.random(n_points)\n",
    "    angle = 2*np.pi*np.random.random(n_points)\n",
    "    points = (r*np.array([np.cos(angle), np.sin(angle)])).T\n",
    "    points = np.einsum('ijk,ik->ij', class_transforms[classes], points)\n",
    "    points += class_centers[classes]\n",
    "    return classes, points"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "yvf85D4KqSTW"
   },
   "source": [
    "Let's plot a bunch of random points drawn from this distribution to see what it looks like.  Points are colored based on their class label."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 282
    },
    "colab_type": "code",
    "id": "CXy5-cJkqSTk",
    "outputId": "afb38088-aa6f-4414-98b2-285b473b140c"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x1584692d0>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plot\n",
    "classes, points = generate_data(1000)\n",
    "plot.scatter(x=points[:,0], y=points[:,1], c=classes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "rskLHEI9qSUg"
   },
   "source": [
    "Now let's create the model for our CGAN.  DeepChem's GAN class makes this very easy.  We just subclass it and implement a few methods.  The two most important are:\n",
    "\n",
    "- `create_generator()` constructs a model implementing the generator.  The model takes as input a batch of random noise plus any condition variables (in our case, the one-hot encoded class of each sample).  Its output is a synthetic sample that is supposed to resemble the training data.\n",
    "\n",
    "- `create_discriminator()` constructs a model implementing the discriminator.  The model takes as input the samples to evaluate (which might be either real training data or synthetic samples created by the generator) and the condition variables.  Its output is a single number for each sample, which will be interpreted as the probability that the sample is real training data.\n",
    "\n",
    "In this case, we use very simple models.  They just concatenate the inputs together and pass them through a few dense layers.  Notice that the final layer of the discriminator uses a sigmoid activation.  This ensures it produces an output between 0 and 1 that can be interpreted as a probability.\n",
    "\n",
    "We also need to implement a few methods that define the shapes of the various inputs.  We specify that the random noise provided to the generator should consist of ten numbers for each sample; that each data sample consists of two numbers (the X and Y coordinates of a point in 2D); and that the conditional input consists of `n_classes` for each sample (the one-hot encoded class index)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "Q5s_qNouqSUk"
   },
   "outputs": [],
   "source": [
    "from tensorflow.keras.layers import Concatenate, Dense, Input\n",
    "\n",
    "class ExampleGAN(dc.models.GAN):\n",
    "\n",
    "  def get_noise_input_shape(self):\n",
    "    return (10,)\n",
    "\n",
    "  def get_data_input_shapes(self):\n",
    "    return [(2,)]\n",
    "\n",
    "  def get_conditional_input_shapes(self):\n",
    "    return [(n_classes,)]\n",
    "\n",
    "  def create_generator(self):\n",
    "    noise_in = Input(shape=(10,))\n",
    "    conditional_in = Input(shape=(n_classes,))\n",
    "    gen_in = Concatenate()([noise_in, conditional_in])\n",
    "    gen_dense1 = Dense(30, activation=tf.nn.relu)(gen_in)\n",
    "    gen_dense2 = Dense(30, activation=tf.nn.relu)(gen_dense1)\n",
    "    generator_points = Dense(2)(gen_dense2)\n",
    "    return tf.keras.Model(inputs=[noise_in, conditional_in], outputs=[generator_points])\n",
    "\n",
    "  def create_discriminator(self):\n",
    "    data_in = Input(shape=(2,))\n",
    "    conditional_in = Input(shape=(n_classes,))\n",
    "    discrim_in = Concatenate()([data_in, conditional_in])\n",
    "    discrim_dense1 = Dense(30, activation=tf.nn.relu)(discrim_in)\n",
    "    discrim_dense2 = Dense(30, activation=tf.nn.relu)(discrim_dense1)\n",
    "    discrim_prob = Dense(1, activation=tf.sigmoid)(discrim_dense2)\n",
    "    return tf.keras.Model(inputs=[data_in, conditional_in], outputs=[discrim_prob])\n",
    "\n",
    "gan = ExampleGAN(learning_rate=1e-4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "Lnd0Wk9WqSU_"
   },
   "source": [
    "Now to fit the model.  We do this by calling `fit_gan()`.  The argument is an iterator that produces batches of training data.  More specifically, it needs to produces dicts that map all data inputs and conditional inputs to the values to use for them.  In our case we can easily create as much random data as we need, so we define a generator that calls the `generate_data()` function defined above for each new batch."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "3o85U5VJqSVG",
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Ending global_step 999: generator average loss 0.87121, discriminator average loss 1.08472\n",
      "Ending global_step 1999: generator average loss 0.968357, discriminator average loss 1.17393\n",
      "Ending global_step 2999: generator average loss 0.710444, discriminator average loss 1.37858\n",
      "Ending global_step 3999: generator average loss 0.699195, discriminator average loss 1.38131\n",
      "Ending global_step 4999: generator average loss 0.694203, discriminator average loss 1.3871\n",
      "TIMING: model fitting took 31.352 s\n"
     ]
    }
   ],
   "source": [
    "def iterbatches(batches):\n",
    "  for i in range(batches):\n",
    "    classes, points = generate_data(gan.batch_size)\n",
    "    classes = dc.metrics.to_one_hot(classes, n_classes)\n",
    "    yield {gan.data_inputs[0]: points, gan.conditional_inputs[0]: classes}\n",
    "\n",
    "gan.fit_gan(iterbatches(5000))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "m91nmqWgqSV1"
   },
   "source": [
    "Have the trained model generate some data, and see how well it matches the training distribution we plotted before."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "JqJCBFIcqSV3"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x160dedf50>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAD5CAYAAAA6JL6mAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nOydd5xU1fmHn3Pv9O2V3jsIUhUVUBSsqLEQS+wabDG22H/GmJjYY9dIiBqjYhcbiKKIVOm9d1hYYAtbp957fn/cZdndmdk6W4DzfD4o3HLuO8PynTPvec/3FVJKFAqFQnHkojV3AAqFQqFoGErIFQqF4ghHCblCoVAc4SghVygUiiMcJeQKhUJxhKOEXKFQKI5wbA0dQAjRAXgXaA2YwEQp5UvV3ZOeni47d+7c0EcrFArFMcWSJUtypJQZVY83WMiBEHCvlHKpECIBWCKE+EFKuTbaDZ07d2bx4sUxeLRCoVAcOwghdkQ63uDUipRyr5Ryadnvi4B1QLuGjqtQKBSK2hHTHLkQojMwCPg1luMqFAqFIjoxE3IhRDzwGXCXlLIwwvkJQojFQojFBw4ciNVjFQqF4pgnJkIuhLBjifj7UsrPI10jpZwopRwqpRyakRGWq1coFApFPWmwkAshBPAfYJ2U8p8ND0mhaBryA8UszdtGtvdgc4eiUDSIWFStnAJcDawSQiwvO/awlHJqDMZWKGKOKU2eX/cNX+5ejEPTCZgGJ6R15x8DL8elO5o7PIWizjRYyKWUcwARg1gUiibh4x3z+Xr3EgJmiIAZAmBh7maeXfs1j/a/pJmjUyjqjtrZqTjm+GD7XHxmsNKxgBli+t4VBMuEXaE4klBCrjjmKAp5Ix43pYnfUEKuOPJQQq445hiS2hURIRvYxp1CnM3ZDBEpFA1DCbnimOOOnmfjsTmwCevHX0Pg0uw82O83WEVYCsWRRSyqVhSKI4pO8RlMPuVO3t8+m1X5u+gcn85VXUbRPaF1c4emUNQLJeSKY5LW7mTu7XN+c4ehUMQElVpRKBSKIxwl5AqFQnGEo4RcoWgCpJRIKZs7DMVRisqRKxSNSGnIz4vrpzJtzzKCpsGg1C480PcCOsdnNndoiqMIJeQKRR3YXJRNtvcgvRLbkuFKrPH6u5a8w9qC3QRMA4CleVu5Zt5rXNThBI5P6cSozD7YNL2xw1Yc5SghVyjK2OvN550tPzP7wHr8RpDWrmSu7DKCc9oOpDDo464l77C1aB82TSNgGoxrN5j7+pyPJjT8QYO8ohLSEuNw2q1/VhsK97C+YE+5iANIwGcGmbxjLl/sXohLc3BVlxGc224wKY44Pt4xn092zKfUCDAioze39BhDejUfGKY0+TVnMxuL9tLek8qozD7YNRsh02BzUTZu3UGneGUbfbQjmiNvN3ToUKl6dipaErtKcrlm/quUhPyVjjs0ndGtjqMo6GVh7hZC8rAoawikBHOdB7nNg03oGNKk28B4bh93CiWGj6fWfEmpEajx+Q6h0yepPRsK95T7wOhCI9nu4eORd5Ngd4fdUxzycfOvE8kqzcNvhHDqNuJsLm7pPoaXNk4jZJqY0qSNO5n7+17Ij9mrWFWwiy5xmVzTNbxuXkrJioM7yPYepE9SezrFpdfnrVQ0IkKIJVLKoWHHlZArFPDQsg/4ad9qIv1rsKMjBZVE/BDGRjdyoweMCnUDusTRz8eQIa1YdXBnmEGXDIG5Oh652wUmkB5AP74IERf+dKdm5+YeYxidMIB3f1jM6u3ZdGuTxrVnDuXzg/OYsmsRwSofLgBmlVciAE1oGNJEQ+DQbDw/5BqGpXUDIMdfxG0LJ7HfV2C9LmkyKrMvfz3+t+hC1US0FJSQKxTVcOaPf+dgsCTiOTtamZCbYedCU9MgGEHonAYJ5xXTzpPKzpKccrtcKcGYkwwHbWAesgOQiA4+9EHFEQ2hB8Z3ZtXHfoIhA1NKNCFw2HUcJxVRmlxsjVCoI/c5QAPRzo9whcdalQ6eND4bdS8Aty6cxPK87Rgcvs+l2bm155lc0fmUGsdSNA3RhFx91CoUQLLDE/WcLvSIZlpSAsEo3iwBDa8RoG9iey5sPxS37rA0+qANCvQKIg4gkMU6keZUOhrLlu/DHwxhll1gSokvEKLoVycyBMbqOIxZKZjr4jDXxmH8kIqZVXODjD3efEpDfgoCpazM31FJxMHK5X+2s/Z91KfvWcFFs57j5OmPMn72C8zev67W9yoahhJyxTGHYZrMXb2ND35aysL1O5FScnWXUTg1e8TrHTYbj/Ufj6vKeSFAH52PyPSH35QQQkcjyeHmvr4XMGvsX5g44FZkfpT6gnw7eLVyI69DhEImxjZXxFukT2D8lIrc5rI+GKSw/m8KzGWJyGgfMmXoQsOh2fCbwahmYd5a5PcBvslawt9Xf06WN4+QNNhRcoCHl3+oxLyJUFUrimOKvMJSbnj+I3IKSggZJjZdo2NmCm/edQm7O+fy3rbZ5TlnDUGGK5HnB19Dz8Q2vDX8Fq6c90ql8USigTa80CpHKdIx18Qhcx1ox5Vg03TObTu4/Nplq7MRaxMgUiZek5xk9MdMLmFh7mZrdu7VMJYngD9KeaIGpARhTwTrXQFynwPR3l+e4zYqpIacmo1z2g7CpulkOBPJcCaQ5c2vNIRNaJzWqm9NbykAr2/8PmwtwG8GeXXDd4zM7FOrMRT1JyZCLoR4CxgH7JdSHheLMRWKxuCJD2awJ7eQkGGJWiBksGVvDq9+OZeHrjiTq7uMYmvxPkpCfjJciXSLb1U+W+2S0CrimEJg5baTDLQTC7F7nWiJkrt7n0e3Cvf4AyFMo+xaIa0ZNAASu27jr+dewLSF61nyY5HV4MJfNnCGH/IcYFSYNWsSOvgQdomsklgXrf3ofUoQ8SYu3cHlnU6mKOjjq6zFODQbATPESek9uafPuLL4BY8NGM+di98hZBoEpYFLs5Pk8HBT99NrfE9DpkGuvyjiud2leTXer2g4sZqRvwO8Crwbo/EUiphjmCazV23DMCvngoMhk2mL1vPQFWcQb3cxIKVTxPt1oSEQyIi1LRZCh7aZCUwafkt53n3r3lz++ekslmzKsu6sIOBgCelLt/6GncH9fL1rCX6H38qlHxJoDWjrgyyXJeCmQLQKIPoUI5ckHR7LJq2ZuAkyJECTeI0AH2yfy3ODr2JCjzPYUZJDG3cyma4kKjIwpTMfjbiLz3f9yq6SXAanduG8doPx1KLRhi40kh1x5AfCF4tbu5NrvF/RcGIi5FLKX4QQnWMxlkLRWEhJVL8Tw6xd9VamK5F9ZSV60TgYLCkX8T25BVzz9GRK/RXTDtazNDvoXf1k9LRx/6638O0IQjropwB+DWN+MpTosN+Bfmo+sncJwmsDj4H0CcxfkyHfZom7BEJlM/j9DoxcB9qwQrRWAfxmkFc2fMffB17BpsK9rCvI4qT0HmEbhVq7k7mt51m1eh8qIoTg993O4OUN0yqlV1yanVt6jK3zeIq602Q5ciHEBGACQMeOHZvqsQpFOTZdY0jP9izZuLu8AgRA1wSnDehWqzFu7j6GZ9Z+FZYPrkgHj7WRxhcI8cdXp1QRcQCB0MA9ugjTE2S/NCgvGNGtebjUTPSTDmLMSAUpMOYko/UthjYBZLGOOS/Z+mRym9a9fo3DtYsCDDBXxCPG5iEEbCzay2WzXyivLxfAoJQu/HPINbWaddfEJR1PBAH/3vwjBwMlpDsTub3nmYxtM6DBYytqJmZ15GUz8m9qkyNXdeSK5mL3gYNc+8yH+AIhvIEgHqedRI+Ldx+4gvSkuFqN8fGOeby5aQalRqDSAiJYG3ieH3w1J6R3567Xv+SXVVsjD2IzcQwvwkyLXhUiQ2DMTYaDVrWM6ORF9CvGXJgEQYE+tNAScoAiHWNxkjWDP4SQ6OfkIuzR/43raCQ63Hh0B90TWnNd19Pol9wh4rWrD+5i2p5lmFJyZpsBDEzpHLHaJWQayj+mkWj0DUFKyBVHCqW+AN8t3sDWvbn07pjJ2ME9y/1RaoshTQoDpXyTtYR3t82mIFhKe3cqd/U5j1GZfdiTW8DFj/+XQDB8NygAmkQfk4dwR9+4IyWY85OQB8pqwh0m+pm5GLOS0UcWVBJoaQIBgfF92uEcvJDo43Ko68bMc9oM5C8DxlcS6dc3TufD7fPwmyFA4tTtXNBuKH/qW7cuS1JKJBJN7RatF9GEXJUfKo45PC4HF4/o36AxdKGR4ozn6q6ncnXXUzGlWUmcdh0owGHTowi5tBYrqxFxAJntQB6oULse0DDXehCt/VbVSwWEBtIpEQOLkMsTLDEXkmSnB78RrDYVVJVpe5czNK1reXnijuIDTN4+t0zELXxGkK92L2Zcu8H0TmpX45gh0+CNTd/z2c5f8RoBuie05v6+F3J8lIVlRd2IyceiEGIyMB/oJYTYLYS4MRbjKhRHClVnmF1ap0YVcRJCaEMKqx3P2O3EXJJI5T37EpERRCQYiAhTMCFAa+dHG2qN7XbY6b6mD65FrZBeLeLO0Wj8bfXnnD7jrzy1Zgo/718b5t0CVp34L/tqt+HnidWf8/GOBZQaASSwqSibOxa/xZaifbUPShGVmAi5lPIKKWUbKaVdStleSvmfWIyrUBypBBx+tHZ+0CsKoARdog8vROjgiKTGlFXXrImrXDcOgMBcHwduExllgi10EJkBSAji9Yf4dd1Ocnb7MeYngkGdxNxnBvl810Je3zg9rGSz7NWwIHdT1PsPpW3z/MXMyF6Fv8q3goAR4t2ts2ofkCIqKrWiUMSYoqCXG+f/i+CAEoTbjdzmhoAG8SFEm8OLm/2S22OWWcdWwgR8UeZYRTZICkFAIG2SiDvrddB6lCDznMi9TquipciOMTMVfUQ+uOu2LiYhau38usIsXtnwHaNb9aNfUnuEEPyUvZqX1k8l23cQu9Bx6fZy07DKL1OyuTi7TrEoIqOEXKGIIX4jyJVzXiY/WILQQO/lxYw3MJcmQqmO3OzG2OzB3sfH7b87i02Fe1l9cCdGRaHUsDb3hCKotNNAGIAzioiXIdoGEW2CcFwx5rIEZJYLSjXkLjeiZ2nMXq8hTf637Rc+2DabbgmtiLe5WJq/vfx8QBoEQlEWfIF4mxtDmsoqt4God0+hiBFrDu7iwlnPss9/eMOQDAhLxE1heZabmvX7DXEs2LqNFzdMqyziWLlu0aMU9CrpDF1aIuwkol1Lpft1EDbr/9qgInCYVprHXrO9bX0wkGwsyq4k4rVhbcEuHlz2QdSNWjuKD/DD3pWsLditmldXg5qRKxQxIMdfxO2L/hPWDUhmO8oqTCpPn4OGwZuz5qD3jZzs1np4MSXIzR5L+HVp1ZE7JJRqh+vHa4MGoncxck08pAWRfoFwtgxR9JshFuZuYln+dgandik/HjRDPLx8MgtyNqELHROTLnGZvDLsBhIjdEs61lEzcoUiBny9e3HExhOVfccrIKs5R5lFbi8v+jm5aKflgdtAbvNgLkvA+CkVY3l8rRcuhQCtkx86+TBnpWAsSkCGymrPWwBeI8jcA+srHXtn6ywW5GzGb4YoNfz4jCCbirL5++rPmynKlo0ScoUiBmSV5kdc0BOtAxVMsiqgg9Y2go95BQ4Jrbkq3lrkNASEylIzWS7Mra46VaGIQ37luU6MX1KQexzIYq1FCPr/ts3m1B/+wt9Xf0FBoJQvdi0Mq3IJSYPZ+9dHfJ+PdZSQKxQxYGBqZ9x6eFce4TJpPVjDYdfRtTJB1yWioxeRGi5IlrFX2a9cHekXkOMI/zAwBXJt7SwFKox++LdFNswlSRizUqAFCDlYTSy+zVrCjQv+hTcU2bpAIgma0RdPj1VUjlyhiAFjW/fn9XkzKVlpYJZqiJQgrj5+hnTsxMtnX8/WvblMX7yBOdkb2BK/AzOlilBJDuusKFuwzDCQXq3MRSvCQ02BzLNBaqhSBYuURKxokdkRzLEk0IJsUULSJNubT8/Etqwt2B22EalrfGbEtnvHOmpGrlDEgJlLt5A/24GZY7fKDPc4Cc1K4fY25wHQtU0at55/Ms9d9RvcGaLS0qdT2CwHQmFtta8kwi4TnJGmzGX9O+ckY65zI4NlPuR+gczXrRy4LDtmgMzXIRBB3Q2Buc3VItIrhwhIg/WFWTh1W/mmKYem49EdPHLcxc0cXcskZqZZdUGZZimOJkxTcuaDb5JX5K10XACjBnTlhVsvrHR8e/F+XtowjWV524m3uxiZ0Ytpe5aHV7yUzdJlrh3z1yQwDo0aXgWDZlrHDi2gpgTR2vqs/p1ZLijRICMA+x0VFlkrpHpa+dGHRe7y01xoCHSh0S+pPYNSu3BxxxNpVaUhxrGGMs1SKGKMlJIVW/fw3aL15Bd7w88DK7buDTveOT6TF4ZcC8CKLXt47MNpFO5JBKeJ6ORFFtkgx27VfHfyonf1ow0pwFwZDz6dMBEv6w6kDS20rinRocCGqTkhtyxvr5mQFoJ4AzZ7Ko9hCOQ+J7KoFJHQcvLPJhJTGmwu3serJ9yIQ1NyFQ31zigU9WDn/nxue+kz9uYXVVs5kpboiXpu7Y593PryZ/gCIUCAV0euP7SAKaymy2tsGJs9ENTLFiUjlyyKDn60jCDaGfnIoLDsYhcnHc4wmxoUaVa7uEhjSJAH7C1KyA9hSsmS3K2clNGzuUNpsagcuUJRR6SU3Pby5+zJq17EXQ4bN559QtTzb3w9r0zEK3Kok3OFP/v1snRIlLpz3XJCMbe7MEs00CRym+ewjzlY7eB8egQjrgrnXS0oUV4BQxp8tutXPt25gKJg+DcfhZqRKxR1ZtW2bA5GSKVUxGHXmXDecM4e1jvqNRt3H6jlE6sxVQFLnLe6MYUE4sFpWOJfERMrXRNxLKtps2gVvVtRc+I3Q/yyfx0LczbzxsbvmXjiBLoltG7usFoUSsgVijpS5PWjVeNY5bTbmHj3pfTv0qbScW8gyPs/LmXawvXYdA2Xwx5lhLoiysoXrZicISdnnNiDOSu3U1jiO3xNNTtJtWGWtW5LxmcG8ZtBHlv5Ce+dckdzh9OiUEKuUNSRAV1aEzSi55IzkuI4rnPlGWPIMLnxuY/Zlp2Lv6zhhMOmowlRqRF0LPAHDZyajRlP38zD/5nKnNXbLB2XMkKzCwmpQbSM2ncQak4ksLVoH0+u/oIZ2asImAYnZ/Tk7t7n0dqd3NzhNRtKyBWKOpLgcXHHhSN45cs55aIMVv13aoKHl27/DUIIgiGDX1ZuZXdOAd5AkB378ytdHwgZ2HSN1DgPuUUl5WOYZoWdQdVSltcOamG575Xb9mDTNZ6ZMI7NWTms3p5NelIcD/9nKsX+soYXEogz0YdV362opWFg8u2eZeVb9WftW8vy/O18NvJe4u2uZo6ueYiJkAshzgZewtojNklK+VQsxlUoWipXnjGYPp1a8dHPy9mXX0THzBRGD+zOiOO6YNM19uQWcsNzH1Hs9Vt+3FISMsNn3poQpCa6KfL68AeNw4unAqr8gYrCLtr60AYUW77lgNztxFyZUJ4+2ZKdxy9rtjCqXze6t0une7t0AC4fPZC3i6cjAxrCZUJSqFpf85aGKPtvRb8VE0lhwMv/tv3CrT3PbK7QmpUGbwgSQujARmAssBtYBFwhpVwb7R61IUhxtHPTPz9m+ZY9FWbXkXHbbYRMk6BRtWKk7L5K2/PLZCwtgDa8oFLfTmmA3OO0vM/L7hftfHST7Rg1oBu/O30wKQkeSnwBzv7qafyJR1b1hw0Nh25HF4KgaURsJq0heKz/pZzTblAzRNg0RNsQFIvywxOAzVLKrVLKAPAhcGEN9ygURy0lvgArt+6tUcSFAE3XsNkirTKWlRtKQdWSRNGzNKz5stBBtPVXahwhhWCLsZf/zVjK+L/9j5yCEuJcDp4YdQm2lmSwUgG70GnlSirf1XlCWneeHngld/Q+h8cGXMpzg69GRPkKYSL5x5opFId8Ec8fzcQitdIO2FXhz7uBE2MwrkJxRCKljNrBRwirqkVKaJeexLVjh/D0RzPrNL7wRFloNTmcM9dBa+9D5tkJ7jMoKPHyxPs/ICWU+gOM7DyIWc4lmGXNoWUQ0C2vl+bCLnQmj7iTjnHp+IwgAnDqlSt7pJR0jEtnY+GeiG+xTWgsyd3Kqa36NknMLYVYCHmUwtQqFwkxAZgA0LFjxxg8VqFomcS7nfTumMmaHdmVNgzZdY2LR/Tn8tGDsOka7dKTME3JxKm/4g8WYtQwgz+EzLODxx8uugKrexASDDDXxVkt3gDDlMxete2wweIWiUxMQhtxEOHTkEIihLScE6tM1qUBMscBJoj0IMIePc5oRo014RA6Q9O60THOyuW79MilmUIIXh92I1fNfZW9vvyI19i1lvltozGJxefvbqBDhT+3B/ZUvUhKOVFKOVRKOTQjIyMGj1UoWi5/vfYsEj0u3E5LkDxOO+0zkrntgpPp1CqFdumW+ZOmCSbdM57+Xdpg12v3z9Hc6LH8USqk1aUEc5ezrHql7FeBHSrs7qwosNIUUKhjTk/DmJmK+WMaxvwkzAN2S7gNkCEwC3SM79IwFydgLk3AmJ6GsTu6jWyire5t2OxC4+SMXvx94BW1uj7B7ubP/S/BpUUQewFD07rVOYYjnVgsdtqwFjvPALKwFjuvlFKuiXaPWuxUHAuU+gJ8v2Qju3MO0qdDK0Yd3xW7Hn22mF9Uypod+3j4rWn4AkFCYQugFYgPofUuQaQHwadh7nAhd7ir3fRTI6KsnNGngV2CaYLUrKbRFdEk+ul5iLjI8aU7EsgJ1M5J0SY0ru16Gjf3GFPncF/bMJ0Pd8wFBLoQSOCfg69hSFrXOo91pNBo7odSypAQ4g/AdKzyw7eqE3GF4ljB43Lwm1OOi3p+4+4DbMrKoVOrFPp1akVKgodT+nXm8tHHM2nqwuoHL7ZhLm6opWsVO1wpLBGXwvIuF0T+zi7B3OVC710acdScQBFOoeOXNRtwGdLErKcZ+u29zuI3HYaxIGcTcTYnIzP7HLNNJ2JSRy6lnApMjcVYCsXRji8Q4u43vmTF1j3Wzk5T0i49iYl3X8L8dTv57/dN9W01sguidUqCU0ZuRiGBYPUz/5A00RBhHX6q4tTtjMzsU7twI9DOk8olHVVthdrZqVA0Mf/6Zh7Lt2RV2uW5ZW8uZz00ieQ4J8FQU7gQyrKVyci1CqJ1ANGjBHNOSthZzSawtQmhazpuzUGpESBUZfZt1GLJ06XbObP18fRLal/P16A4hBJyhaIRMEyTyTOX8eHM5ZR4Awzv05E7LhpB27QkpsxdU0nEDxEyTHIKm2qjTpnRVtX0SkoQ7aSCw0c6eGGHu9I1p/brxmO/HUNQGuT6i7hpwZthQq4jIoq5Q7NxUnpPEuxuzmozgBPSuketC1fUHiXkCkWMmbpwHU9O/pES3+Hdhz8s3cT8dTv57LFrCISqepA3J4dFtFf7DBI9TjobySzI3syu3YWQW9n61mHTGTu0J4kOq2FGmjOB/ikdWZm/A3/ZtnkNgU2zYUTYfdnek8Yzg36nxDvGqMYSCkUM+Wz2Sv723g+VRBws50FfIMhHPy/n5L6da7TDag4OFJSQW1TKjLlb0LPdZW3iKkdqmCbZuZUrUp4ffA3jO55Ekt2DW3cwIrN3xAVMgeCsNv2PSRH3lfr58f3ZfPLcV6ydv4FY90pWM3KFIkaYpuS1r+ZFTJuA5Xb4vxlLOb5rGzxOOyX+lmUdm1dUSl6RVYkSrXGG026jZ4fK+0Bcup0/9j6HP/Y+B4D5BzayJG8rwVDl90EiWZy7jesbqcw7d28+sz9dQMAX4MRxQ+jUp+ly76Zpsui75cz7ciFxSR7Oum40nfpa22u2rdrBvaP/QigQIugPYnPYGDCqL49PuR+bPTYSrIRcoYgRJf4AxV5/tdf4gyEWbthV7TUtgaq+i2ClVTpkJDO8d6dq701yeCJ6rAsEac74mMZ5iJkfzeW5G14HwDQM/vuXj7nojnO46amrGuV5FTEMg8cuepYVP6/BV+xD0zW+em06t798A2ffcDqPX/o8RXnF5deHggYrZq3h24k/cOHt58QkBpVaUShihMdpx+U4uuZG8W4nyfFuUuLdXDpqAJPu/S2aVn1qpE9iO9KdCYgqaRmnZmN8p5NiHmNRfjHP3fA6AW+AgDdAKGAQ8AaY8up3rF2wMebPq8q8LxezYuZqfMWWWZdpmPi9AV694y02Ld1KTlZu2D3+0gDTJv0YsxiUkCsUMULXNK4/a9hRJebHd2vDT8/ewo/P3sKfxp9GnMtR4z1CCF4eej0dPGm4dTtxNicuzc5dvc+lf3LsfZYWTVuGHsHeIOAL8NMHs2P+vIrk7Mnj3b98hK8k/JuYzaGzZt6GqGsCRnU7d+vI0fMTp1C0AK47cxi60Hhr+kKKvQFSE9wYpiS/hmbNLRGXw8YNZ59Qr3vbeVL5ZOTdbCrKpijopW9Se9y2mj8E6kPUdUNJzBcVK7J67noePufv+Eqjp9PadmtNYlpCmNA73A7GXnNazGJRQq5QxBAhBNecOZSrxw4hGDKw23S+mLOa5z79GV+g+rLDk/p0ZPGm3U20IQjiXQ46ZqawNTuXtEQPGUnxrN2xD4AEj5MHLhvNwG7t6j2+EIKeiW1qvrCBDDtnIEaE98zhdnD6FSMb5ZlSSp6++mW8xdG9z4UmGHRGfx79+B7uH/tXzJCVcnHHu+g6oBO/+cPZMYtHCblC0QgIIXCUVSRcNOI49uYV8p/vovunOO02LjttEPPX7WyS+FwOG3dfMorzT+rHm9/O58OZy8nKKSQzOZ5LR/bnujNPwGY7MjKviakJ3P3vm3lhwptI08QImdidNsbdPIZ+J/dqlGfu35lD/r6CyCcF2B12zr1pDL4SH71P6MF7215n5uS55OzJo/+IPgw963g0LXbvb4PdD+uDcj9UHIs88f4PfDV/bZiroSYEPdtn8O4DlzPirtesHp+NSILbwW0XnsJlpw7kH5N/5JsFa8O+LaQlevj33ePp3Dq10vGDxV5MU5Ka6GnUGOvD/l05/PLJfAK+IMPHDaHrgOqraxpCXnY+V3W5nWCUElKhCRwuB0LAE988xKT6MuIAACAASURBVPGn9ovJc6O5HyohVyiaCH8wxP+9PY1fVm5FCAiETBw2HZAEQyYJHieF1eRbY4XdpvHGHy+hR7t0xj44kUCUunebrvH+g1fSo30Guw8c5JG3p7F+534Q0LlVKk9cfw49ypo6H2vkZedz+7AHydmTV2MnjYS0eD7ZOwk9Yku/uqGEXKFoIWTnFZGVU8CCdTt4/6elNebOG4POrVJ46qbzuPH5jynxBaJe57TrfPbYtVz3zEfkFZVWqg9PcDv55u83kuBueuvY/TsP8Ok/v2Ht/A107NOe8X+6gC7H1b4iZuOSLSyathx3gotTf3syaW3CzcGisXXlDu4e9ShBf5Cg//DfnRAi4uKqJ8HN36c+zHGn9K71M6LRaH7kCoWibrROTSAzOZ67//Vls4g4wM79+SS4HfiD1T8/EDR48bPZeP2BsE0+QcNg+qL1XDrq+MYMNYxdG7K4Y/jD+Ev9hIIGm5Zu45dPF/C3rx5g0On9q71XSskLE97kp8mzCfpD2Ow6bz38AQ+9fyen/KZ2FTov3PwmpVXMzYSA+GQPRfkl4TcIqimtiQ1HxmqGQnGU4Q0E8fqbzzzLlHDXG1/VWJ4nga3ZuQQiVIX4AiF250RZ8GtEJt7/HqWFXkJlKSHTMPGX+nnxlok1vp7F05cz88M5+EsDmIZJwBfE7w3w1FUv4y2JXoFyiIA/wIaFm8KOSwneEh+uuPBvJ7pNp8/wnrV8dfVDCblC0Qx4nHYSPM3bzWZTVk6NDZ91DQZ0bRuxgsXjtNO/S+OXF1Zl5ay1EQV73/YDlBZVX68/473ZETfvaDaNZT+uYumMldw65H7GxV/F9b3v5IuXp1JSYM2yszbv5eaB90WdXLviXAw9ayCuOCeaJnC6HbjinPz5k3tjkh+vDpVaUSiaASEEf7jwFJ77pOb68ubEMGH8yP7s2JfP2h37ylMxdptOm9RERg1o+v6YngQXpYXhbeY0XcPhqtyQOeAPMnPyHOZ/tYjkzGSKD0ZIfZSxZcV2PnpqCn6vtWawe+MeXr/rbd68713O+N1Ilv24ipysvIj32p02ho8bwpWPXMKl95zP8p9Wk5Aaz2mXnUxiWkIDXm3taJCQCyHGA38B+gAnSCnVCqZCUUsuHtEfj9POG1/PZ19+EW1SE9h/sJigYWKYslF3JdYWTQg+/HkFr//xYt6Zvoiv5q/BMCVnD+vFTeecWG0z6cbgpw/nRKzfdrjsjL5iBHbHYSH3e/3cPfJRdm3Yg6/Ej6Zr6DYNm0MnFKhcqWMaJrM/W1Au4hUxggYzJ8/BNCQy0jcYYW23nztlIbM/XUD7Xm3565cPkNmh6Sp6GlS1IoToA5jAm8CfaivkqmpFoahMyDA568GJLXIrf2ZyPN89+fvmDoP8fQe5quvtBCKI7cDR/fjb1w/hqpCu+ur16Uy8/138pZWv120auk3HCJnY7DoIePSje/jr+H8SqKaCp7Zoukbb7q15a+2LMfdeb5SqFSnlurLBGzKMQnFMIKVk5da9LNqwi8Q4F2OH9CQl3g3A8i1Zjb4RqL6kJLibOwQA5nyxkEhSo9t0Bp3Rv5KIA8z6ZF6YiAO4PE4mPHcNhbnFeBLcjBo/nOSMJDI6pJG1aW+D4zQNk9ysPDYu3kKvYd0bPF5taLIcuRBiAjABoGPH2DugKRQtGcM0eXDSt8xbswNvIIjdpvPiZ7N46faLGNarA75AqEm6BqUkuMmvZkHQpmuVdp66HDauHRs2AWwWQoFQxNSGNM1K9dyHiE+OiziOaUq6DexCr6GVO1wMPK1fTIQcrJ2dUbfwNwI1Vq0IIWYIIVZH+HVhXR4kpZwopRwqpRyakZFR8w0KxVHED0s2Mmf1drwBa0t3MGTgCxrc+foUgobBoO7twrbuNwZxTkfUDwyHTaNPx0ycdp14lwOnXeeaMUM5a2jj+JXUleHnD4l43O6yR6wBv+C2s8Jm6UJAYnoCPYdUXqTdsGgz3//355jFGgqE6H1i08zGoRYzcinlmKYIRKE4mpkyb3XEzTe+QIjvFq7n/JP68dAVp/OPyT8RMowaywLrS05hCUN6tmfxxt1h59xOB2/96TL25RdzoKCYrm3SmmXXZjTadGnFVY9eyvtPfEYwEEJKicPlYNwtY+k+qEvY9UPGHs9lD1zI5Ce/wOawIaXEk+jhH1MfCUsHP3vDawQjVA8JAa54F96immvMD6HbNAaPHYArzlX3F1lPVPmhQtEElERYoDvEzOWbOf+kfpx/Uj/6dW7NF3NW8+v6HWzdmxexZVpD0DTBbRecwt/fn8H2fXkYpkTXBDZd48kbz0XXNNqmJdI2LTGmz40VVzx0MSeeN4SfJs/BNExGXTqc3if0KD9fmFfED+/OYue6LHoN684l95zPeTefyeo560lMjee4kb3Rq1Ta7N+Vw4614R9sAHaXg4TU+FoLuaYLjJDJ8pmrubb7H3jl1yebpHqloVUrFwGvABnAQWC5lPKsmu5TVSuKY41/fjKL935aGvHcKf0688ofLqp07JG3pzFt4fo6P0cT1q7NaCR6nMx45hYAZq3YwoL1O8hIiueCk/rROrXx651roqSghIMHCsnsmF6plLA27Fi3m7tG/B9BfxB/aQBXnJP4lDheW/gUqa0Pe6lIKSkt8uJw2bE77EybNIN/Tngz1i8FTdcYdvZAnvj6oZiN2VhVK18AXzRkDIXiWOCqMUP4YOaysBm2w6Yzsn94WuDE3h2ZsXRjnZtMRBNxgeV5/vi1Z2Era4t2xuAenDG4R+QbmpiAL8ALE95k1ifz0W0amq5x45O/44Jba5wXlvP8jW9QcrCkfOelr8RP0B/i3w+8xwP/vQOAqZNmMOmB9ykuKEG36Yy+/BQyOzXOmp1pmCyevhwpZaNX9qkt+gpFE5CZEs9VYwbjtB/+Wu8o2x15/vBwr+qzhvYiLSFy1YVeR1HQhOCMQT348P+u4tQB3Wq+oZZs3ZvL85/M4pG3pjF90QaCRv3LJ1+4+U1++WwBQX8QX4mf0kIvE+/7H/O/rt03d2+Jl3W/bgzbPm+EDOZ9aY3x4s1v8sKENynKL0aaklAgxE8fzGbJ9OVEWwHWIvQCrQuirHnEillruPOUR7go9TpuH/YAi75b1qBxw56jbGxjgwztQno/hNAucJyEcF+I0Fqe+b6i+ZBS8tPyzUyeuYziUj9nDO7BFaMHER9lQbGgxMd5j0yiNELzAiFqZ6inCcENZ5/AbRec3NDwKzF14Tr+9t6M8oVZt9NO97bp/PvuS8s7I9WWksJSxre+iaAv/HX2PrEHr8z/R6Vj3hJf+U7NpT+sRLdpLJ6+nGn/+Sni+PHJHm594Xqeu/H1iOWLdqcdV5yTorziSsetXaB2/PX0iNftOiMuOpFzfz+GP1/wVKVdo06Pgwf+ewcjLxlepzGPOj9yKb3I0i8hMAf0tgjPFQhb+FfUpkD65yHzbwWCQAhwg56BSPsMoSU1S0yKo4NdBw5y38Rv2LKnssGVoMZ+BoDVROLXV+6MaUzeQJAx971ZXkp5CJfDxr2XnsolIwfUaby92/YxYcC9Ec2s0tulMnmXlb8uLfLywoR/MXfKQoyQgWlaVSu6rlXbOxOsuu6I2+uxtvf/4ZUbeevhD/AW+wgGQ0hD0n9UHzYt2Ro2tpUmkdV+kDrcdpxuJ8ed0ouNS7eRG8GjpVWnDN7b9nq1cYe9jihCfkSmVqRZhMy5EIqeBP/3UPoeMudCpG9m08ciTWTB/YAXS8Sxfm9kI0smNnk8iqOLDhnJvHHnJWhV0ikSa2FTE6Ksy1BkRFnOIBgymLt6G9MXbSCnILpxVG1YtXUvmhaei/AFQny/ZGOdx8tonxbRHVBogn4VmjE8Mu5JZn0yn6A/hGlIkBDwBmoUcSCqiAMYIZPh44bw8OS7CAVDmCETKSWrZq/DNEycHieueBc2p/VNQ8rqRRwg4A1SWuRl/tdLIoo4WM0xQjX4wdeWI7L8UJa8DcYe4NBXlRAQQhY8CM55CNGERj7GLjCLIpwIgO87SLiv6WJRHJVs2n0Ap8NGsEoJoymhX+dMHrlyDK99OZcF63ZUmrXrmuDU47uxbuc+bnv5c0KGJVAhw+Smc0/kpnNOrFc8bqc9qqGXx1m3ShMAm93GhGev5vW73ilPY2iawBnn5NrHfwvAul83snr2unrFWxOarvHh01OY8so0zAqbsqQpI5po1RYjSgu9Q8SnxMfM3vaInJHj+47DIl4RP4Q2N20swgVE+QsTkRerFIq60Do1IWL1iiYEnTNT6d0hkz9fPZb0pLhyIfU47WQmJ3DPJaP4wytfUFDio8QXoNQfJBAyeOOreTz23+kUeeue/+3XqXXEvL7bYWP8qfXrFnTuTWN49ON76HdyLzI6pDFq/Em8tvApOvRqB8Cnz39Tr3FrQ9Af5IuXvq0k4o2Ny+Pk8gd/E7NqliNyRo4WF1k7pQGiaRcYhd4Kae8LwVVUDsoN7quaNBbF0UnHzBT6dWrFqm17CVYQG4dd56oxgwHISIrny8evZ+aKLWzLzqNrm1RGHteV6Ys34Ivw9V0C3/66juVb9vDhI1fhrsNMWtMEr/zhIm558VMCIaN8ln/l6YM5uW/ner/OE88dzInnDo54bsfaXfUeNxJV+2s2xVKh0AQ2uw2bQ+ey+y5k/L0XxGzsI1LIhedqZMFGrLz0ITSwdUPYOjR9PMkvI/OuBjPHOiBD4D4H4bm0yWNRHJ28cOsFPPrOdOav24EuBPFuJ/931Rh6dcgsv8Zht5X7ovy8YgvnPjIJXyCIP8pXfFNKDhQU882CtXWeSfdol853T/2ehet3UVjiY3CPdrRKabwNRa27ZEbdfVlXojVJjiWaLqw8fhlOj4Pr/nY5Y64aRUIMUyqHOCKFHNf5EFgK3s9AlL0ELRWR8lqzhCP01pD+PQQXg7EP7AMQNuXwqIgdCR4XL952IUWlPoq8AVqnJERccATYnJXDw29NrVXnIV8gxNy12+uVErHrOqf061zn++rDb++7kOUz19S7FLAijS3iNqeNzA7p5GcftJpOhExOOn8oF/3x3DB7gJg9s1FGbWSEEIikvyDjJ0BgOegZYB+CELVL+Uv/L8jil62ab3svRPw9CMfABseEY1iDxlAoaiLB4yLBc9iMqaDEx968QtqlJZYf//Dn5bX2Ntc1QetGnEnHigGj+nLHqzfyxt3vYJomoYBB534d2Lx8W7UVKc2By+3kP2teYP2vm9i/K5eeQ7rSvmfbRn3mESnkhxB6W3DX7Q0yvVOh4EGgrGQpsACZdw2kvo1wRLbJVChaGiHD5KkPf+SbBeuw23RChsFFp/TnT+NPY8f+fMxaipvdpvPbei5QNjVnXTea068cQdambJLSE0hplczMD+fy5FUvtRgxd3qcXP/E5djsNo4b0afJnntEC3ldkVJatedUrTv1IYueRqR93BxhKRR15s1v5jN14XoCIaN89j1l3mq8gSDLN2dFvMdu0+mUmcyuAwXomsCu6zx2zZl0bZPWlKE3CLvDTud+h9fBRl9+CnanjWeue5WAN4BRR2+aWNKhdzuueWw8p112SpM/+5gScmTp4QXJqgQ3NG0sCkU9kVLy4c/Lw3LgvkCIr+atibrjs1VyPO89eCX7DxZT6g/StU1auYHWkUAoGGLRd8vJycqjz/AedB9o7eTudnxnXB5nnTzDY41m03hr7YvN9vxjS8iFy/olI+xs0xKRMgT+nyG0CWydwXkGQjiaOkqFolqkhJIoTYKrSzDsP1jMK1/O5d5LT22cwBqRvVv3cfeoRykt8mGGDBAweMwALvrjuTwy7smIPi1NSUJKfLM+/4gQcikl+L5Blr4LZjG4xiLibqyzj4kQOtJ9JZT+O/ykmY88cA7IHGvmjgAE0n0pIv4uhH7kfP1UHN1omqBb2zS27MkNPydE1GYUgZDBlLmrj0gh/9tl/yQv+2ClXPiSH1awdMaqZhdxgJKDJRQfLInaJ7SxOSK+V8mifyAL/g+CK8DYAiVvIXMvRpr18IywdSLy55cB5q6y2boETOuY92Nk7gVIM79Br0GhiCUPXnY6LoetvKu8JoTVa7OG1mxVja6OBHL25LF99a6wBc2ANxiTckQATdNwxde/NZvNbgtzT2xKWryQS2MflH5I5c0/ATAOIL2f13k8YeZiiXRVjCjHJZgFyJL36vwshaKxGNKzPW//6TJOH9iDTq1SGDukB+89eCWv/OE3xLscYSZbhxjUrV0TR1o3Nizewt2jHuU8z5Vc3n4Cn/7zawK+QNSa+VjhcNkZMKoPop7PsbvsZHZs/JZu0WhQakUI8SxwPpbxyRbgeinlwVgEVk5wBQg7yKqfvD7wz4a4q+s2nmNoWZ68tA43BSAwG7ijbs+qgJQmBBaBuQ/s/ZvNcldx9NCrQybPThgXdvy7J3/P5JnLmDh1gdVAwZTYdR2HXeeBy0Y3Q6S1Y8faXfxp9GPldra5e/J5588fkbMnj5TWyWRv21/peqELpBGbskNfqZ+FU+vX7MHpcXDrC9fFfLdmXWhojvwH4CEpZUgI8TTwEPBAw8OqgJZJ5JmyDno9Zhf2oWAfDIHFHC5DdIFIABltti5Ar39BvzSykXlXgVmW05QhpOssRNLTTevUqDgm8Lgc3HjOiZx3Yl8mz1zG+l376dMxkytGD2rUbfQN5f2/f06gitugv9TP169P5/Ep9/PYRc9ihAyMoIHDZY/Y9b6pad0lk3sn3crA0cc1axwN7dn5fYU/LgBiby5iPx60VmDspLIplR0R97s6DyeEgJQ3kaUfg/dTQIL7UnCdCXm/s2xpw8TcifBcX++XIA/eCUZW5fh9PyDtQxBxV9R7XIWiOlqnJnD3JaOaO4xas2np1ogbmXS7zou3TEQTglDZ+UAzL3Ampsdz5cOXcPGd5zV6P87aEMsc+Q3AtBiOB5Rtx0/9L9j6Ak7L3VAkI5JfQNi613NMO1rc79DSv0BLn4IWdxWanolInwqJT4DWFrCVPSsBEp9AOOq3+00aByC4hnC7Ri94a593lzKEWfIeZs75mAfOwSx+Aym9Nd+oUBwhdOrbPqIo+kr8HNidi6/U36RWs9Fwuh2cdd1oLrlrXIsQcahFqzchxAygdYRTj0gpvyy75hFgKHCxjDKgEGICMAGgY8eOQ3bs2FHnYKWRBWYJ2LoiRONWTpqhXVDyfpn3eanlo5L4V7Q6liHK0E5kzjjCd5MCWnu0zMh9BsPiyb8F/PMqjOMEWw9E2seN/l4oFI1JwBdg45Kt5GTl8twNr+MvPZxecbgdBH2BJrGZrQvuBBdfFfyvyZ8brdVbjQogpRxTw8DXAuOAM6KJeNk4E4GJYPXsrDHiSM/S20FTpZQLn4DAL5TPpP0/wIEfMVM/RXPUIR+mdwAtBcy9VU44wH12rYaQwVUQmE/lDwM/GFvBPxNcY2sfj0LRgpjx3ixeum0SmiYwDZPE1AT0Vjr7dhzA6XbQsU97Ni7e0txhhuEr9iOlbDEz8galVoQQZ2Mtbl4gZZ3KQFo0MrjWauoclg4xIf+GOtlgWk6NzwBu4JB5vxv01oi4m2s3SGCZ1TQjLNBSZKBhTawViuZi87JtvHjzRHzFPkoLveUplH3b93PGlSNp3TWT7at3NneYEek5rFuLEXFoeNXKq4AT+KHsRS2QUt7S4KiaGRlYzuFGylVPFkFoHdj71no84TwRMqYiSz+yFlPtwxGeCxDCXbsB9MyyEsyq27JdoEXKeikULZ8vX/+OoD980VJK+GnyHKQpG907vLYITSBNiW7TsDsd3PHqTc0dUiUaWrVSv9XGZkBK06odF55qfculNK2GFVFdK7QIglozQm+HSLinzvcB4Dwd6/OytHJcQkN4LqzfmApFM5O/92BUu92WsKhZkfa92hKX6KH7wM5ceu/5tOveprlDqkSL39kZC8yS95H7hyP3n4DcfyJmyTvRP+kDc2to4OwEe79GiTMaQjgQae+D3g1wAW7Q2iBS3kZoqU0ai+LYIqeghJ118DevCyeeNxinp3pLgZbCrnVZOF127nxjQosTcThCTLMagln6CRQ9Q/kWf1kARS8go9ShS99MKtsBVERHJD+PELVvVBsrhK0bImMqMrQLCIHeuUXl6BRHF7mFJTww6VtWb8tG1zTcTjuPXT2Wkf27xuwZY689jS9f+46sTXsJRekr2pJYMWstK39Zw4BRTTuRqw1H/4y8+BXChdkLJVH6e2qJRP58s0HCwwhX7bc4y8BCzIP3YubfgvR+bdnkNhBh64CwdVEirmg0pJTc9vLnrNiyh0DIwBsIkldUygOTvmXr3nDHxfri8jh5ZcE/uPov49HtR8YO528nzmjuECJy9Au5eSDK8ZyI6RXhvpiIQi5cCPclYYel9CO932AWvYT0TUOW5c/N4teQ+b8H3zfg/wlZ8Cgy/0ZkpOoThaIFsWH3AXYfKMCo6jYYNJg8s35+JIfYt+MAz97wGld2vIXbhj3Ar98u5cqHLuHt9S+hHQFNLpzultmf4KhPraB3suqtw45H3kUmbB2RSU9CwcNQ7oOiI1L+hdA8la6VRjYy97cgC61SQBEHWgoy6XUofgPLS+wQpZYBmP9Hyw5AoWih7D9YHNFt0JSSrJzCeo+bk5XLLYPvo7TQi2mYHNidy/M3vUHW5mwGnX4cdqet0magpsLhcjDg1D6smLmmRv+Wyx+8qImiqhtHvZCLhAcsr5NKm2lcEB/d20tzn4d0jobgIsAOjmER8+Ky8LGyGX/ZLFuWgOGHosew3toqP5SyFOmbgVBCrmjB9OmYSTAU/s3RabdxYu+O9R73o2e+xFvsq1SR4ivxM/kfn2MEQwT9zWOCddtL13HWdaO574zH2bxsW7n7YlXG/+kC2nZrmeW+R7+Qu0ZDyqvIoufB2A56R0T8PTXmuoXmAWf0TipSSvBX2PlZTgiCq0E4I1QwalDHrkYKRVOTkRTPxSP7M2Xu6vK+oDZdIynOxcUj+9d73BU/r8GIsKgppWTy01OareRw/leLOe/3Y3n2x8eY/dmvzP58AYmp8XQf1IUVP6/F4bLz2/svpFOf9s0SX2046oUcQDhHIZxN6QKnEdlLwIFwj2/COBSK+nHf+NPo27EVH/y0jCKvn9MGdOOGs4eRUEMHoupo3TmTbavCd2o2t5Ph5qXbAKvLz+jLT2H05aeUnxt385Hx7fmoFXJpFiCLX7NMr4QD3Jcj4q6NWjooZQC8U5Der62FTc9l4DwDMMHYDVoCCHeZcVUIHCdbG3X8MwnfBWqHxMeh8HGg7IdUBiHxzwh7z8Z70QpFjBBCMG54X8YNr/0O5pq47IHfsPTHlZXy4DaHDdMwMGPUIKI+5O8/yIZFm+k17IjZ3xhGje6HjcHQoUPl4sWN5xEipc9yHDT2Ui6kuMB5MlrKvyJcbyDzrobQGii3hnWC3sUScUJlv0zAbfVlliGIv99q5GxmhwchUiHjJ0RwBUiflWfXmrfTtkLR1OTvO8iHT0/h12+XkpSeQO8TujPjvdkEvAEMw2DwmAEs+WEloWZuEpHRIY3nf36cNl1aNWscNVFv98MjEu+3YOZwWMTBag03Dxlcj7D3rny9/ycIra0g4mC5C66PMHjJ4dx38TPg/h143yVsVi59UPo2OEeBbbiq+1YccxTmFnHzoPsoyi0iFDTI2rSXrSt3cPHd53P2dafhSXIz9/OFrJq9jlAwFN0Vowk4sCuXW4fcz8Tlz5HZMaP5AqknLb9wsx7I4KIoPTmFtRBZ9Xr/L3Xs4XkIA4JLiGywVQrFryBzL0Xu64dZPLHFGAApFE3BF69MpeRgSaVdm74SP58+9yXxKXH8+/73eOPudygt9DariFeM7cOnpzR3GPXi6JyR650AB2Hlf0IDPYJPgpaK9VbU9eudgfUTKIj8k3hoFT4Exc8hzWJEYvXGWVIGkKWfgO+rslz95eA8W83oFUccS39YGXEh0+60s2jaMn6aPIdgMy90VsQIGqz4eW1zh1EvjkohF+5LkCVvVnEp1K0GD47hUa5/m7oLuW6lZGo7nSidhIy/CaElRjwtZcjK1QfXcajuXQaWgPN7RMoLdYxNoWg6Sou8fPL8V8ycPBe70864m8eQ3iEdsWBT2DfRUDDErvV7EBE2HTUF8SlxFB8sifjPtnWXIy+tAkdpakXomYiU/5bNzJ2A3WriHH8PBJeFbZMXto7grLYRUhQM6ib+OoQ2RT/t/xFCG6i8eSkA/m8xcy9HmkdN7w7FUUQwEOSuEf/Hx898SdamvWxfvZN/P/A+BQcKcLgrV4npNg2b3caHz0wh0Ay7OIUmGHrm8Qw/bwh2Z+XYnB4nlz/QMndu1sRRKeQAwnE8Iv17RMYMSPgrhNZD4Z+R+b9HHhhhtU8rQwbXgj+aGU51s4a6JvYk6NF3hkn/nOi5+uAKZNFf6/g8haLxmfP5QvZu21cpjeIv9bP+101c/efxxKfE4Y53YXfZiU+JJ+ALNF2VSpV/vg6XgysfvpiHP7iT4ecPwe604YpzkpgWz90Tb6b/yD5NE1eMOSpTK4cQQiClH4oep9IsV5Yg866HzLkI4bRqx6vm0wHQwXZ8WfqkavPk6nLqkXLmwvIxF5HTKgBo6Vjt4CLlDQ3wfoNM/Fuz2OgqFNFY8fMafMWRt7XHJcXxSfYkdm/ci27XuXnAvTX6mcQaTReYhkTTNdLbprBnyz669O/Enz++l+KDJRTlFZPZMR3ddmQ4MEbiqJ2RH0J6PyOy4Brg//nw7yMhHOC+FGzdOdxv8xDV/DDq/cF5MZWnAxKCa5H7T8IseLjcJbHS49yXUH13acPaWKRQtCBad84IS1MAaLpOWtsUbHYbnft1wOVxIpra4VBSvtnINEyyNmfz5FUvM+2tHwGIT46jTddWR7SIQ8ObL/9NCLFSCLFcCPG9EKJtrAKLGWY+EUVXmmAWACBcXVL+jgAAGJVJREFU52Dl0sOvEa7RiNR3ynZ51hJjHfi/jnDCDwSsmXXR02Fnha09JL9I1L8WvWuYA6NC0dyced1pYUIoNIE73sWwsweWH0trm4InoZZ9ahsRf6mfSQ+8j2EcPZbSDf14fFZKOUBKORD4BvhzDGKKKcJ5GhBJ/ExwnGRd4xgEnt9itVHTsNImTkh4BKGnWVUmjsFUP1uuSLDsV7Qcug9KP4k4K8f3LZEzXm5EksqRK1oeqa1TePK7R8jsmI7T48ThstO1fyde+OWv2OyHf5Y1TeOM341sxkgP4y32UZRX3NxhxIyGNl+uaE4cR4so66+C81SwD4DgUg7nwV3guQJh61B+mZb4CNJ9IdI3A4QD4RpnVbMcwjeDqCmYemFYtrfCgQxuhOBKJAb4vic8X///7d15fJxltcDx33lnz9KkTVsLXWhlhyJbyw5l3ykqIAiCXi4WkPUigohawQ9YloogXqAgH1T2pYCyiIBsAhcoZZddFgFpSxeaNpPM8p77xzNtk3YmM8lsmcz5fj75wGRm3jlvk5x55nmf55wANJ2GhLcu4esbUzoTd9yIGz/4Xz57/3NCkRAjxw7P+rgNJq1LpCFclbrj3XkBj8aWwfPptuiLnSJyAXAM8CWQszasiEwDpgGMG9f/msZ9l2bVxhxw89Y+hKeg6fmQ/rfrfxloQ0ITkdDEHs9WVbTjVtcUopS8oShN6OJToOuJTFxpcl7oTPfWENqYykun0jxw3aM8cO0jJBNJtj1gaw4/62CGDGvO+ZzJ+25BtTc4RxoiHHzSPoTCg2fRQN6iWSLyCJBtzdy5qnpvt8edA0RVdXq+Fy130azu/OW3QPsM1uzbGQLEXdDUBMSmIkPOR6Tne5u/bBYs+12W5xdDoOUK8OdB+6WsuSJmdWFoPAGv+WQANDEHjd8DmkRiB0B4Z9v5aSpu+jcuZs7fXiERXzW6Fk/41o+mcuwFR+J52Wdu/37LU8w87mrUV5KJJCgEQ4GyN2AORUJ4AY+pP9iH//7VkQQCtXeBs99Fs1S10J0yNwP3A3kTeUV13k32JLyivGzmlzB+HxpYG2k6eeUjVBOw/Koczy9CeAckMhmdvyf5kzggAaThUAD89stg+Q2Z5yna+VfXOq7lYkvmpmLenvM+Lz78ao8kDqC+Mvs3D9AyfAiH/XBq1ufu/u2d2WznTXji9mfoiifYco/NaF/YziM3PcXjtz5d8li9gLDdgZM4/ZrjaWptGFQj8RWKXbWyfrebU4Fs5QKrrNAfWics/1PPb/mLoOTNkgXCu6LzpwC5LrYIEHb1z70RSOs1SGAUmvoYll+Pe2NZ8Ukq7ubVky+WOE5jcnvj6bfwc6z6SHYlue3ie7Pet8KIMW0cesZBHHXuIWyy3QaM3Wg0w0cPo6Wtufc9eP2w0Tbrc9YNJzF0ZMugTOJQ/Bz5DBHZEDcJ/RFwQvEhlZY0HI4ufX21ErU5aHvP294wECn9JdxlF/R+v7c2DPsDQsItOZTM+23Xk2Rfvx5HOx9Fwmt84jKmLIaNaiUQCuTss7l0YXvW72cz99HX+PnBF5FOpko+vbLB5HW5/Ok8f2+DQFEjclU9RFUnZpYgHqSqn5YqsJKJHpipoxLFjXIbyb1Oeyyqq34xRcIQyt23s3/yvSuEkNZL8YLjkOB6q5I4oIlXyb1yZvBcgTcD3/ZTJxHOsglohQkTC1vQ4Ps+F3/3t3R1dPU5iQdDAcLR3DFEGiL8zzXH9+mYtWrQ7+wU8fBaZyJttyHNZyFDfglDbwCybExIf4AuOmplMtfku5B4vILRhmDIz7IuM/SX/xG6/pz7qeFVLblU4/jtv8GfPwV//i747TOt4JYpqUgswqWPnUfb6GFZ7gtz4mXfK+g4n38w31Ui7Id02uf8e89mw8nrIiIEQwEaWxqINUfZfLdNmfnYL1hviwn9OnatGdS1VrqT0MYQcgVxBPBjB0L8jjUfmHwFuh6G6H5ox80UdDGylKJrVl9Tf1lmdUuuLuNRRNzOVFUfXXh0popipv7F8hvQrqeg7S5Eau9KvRmYJkwcxy0fX82Tdz7L3Vc8wLyPvmD8pmM45heHs/G26+c/ABBtjPS7X2cwFOCdOe9z5XMzSKfTeJ5Xtxf86yaRr6Hz0Rx3+Gj8PrdtP13pmaIAknoLwpv3/HbyNXrfVapu0xNA4pnMmvPuRYy6IP0hJJ6CyK6lDNjUORFhymE7MOWwHfr1/GGjhrLBpK/yxjNv55x1DIYCILJGxcRkV4p3534AUJNLCUtp0E+t5JZrdEtmHh0IT65MKKteOHu9cq+FXj8ZNE5b1awi+ZrrF7o67ci8IRgzsHz/oqNz3hcIBtj/+3tmLWoVjoZYb6v6mDrJp34TefSg3PfFMutfG46k4h9agll+MYMbk3tEHkYiu6y6GVgbJJrtwKjW74/bDFyL5y0h1pTtdxa23GMip1x5HOtvPaFHhUURIRwNs/9xfShmN4jV719204m4vp6rC8HiE/C/nI5IDFp+S8kXtuYUR7+cjiZe6PFdEVlZ4Cur7n1Io/vgKjmuHnMKll+N33FbqYI1piRGTRiZdZ48GAqyzqauHtKF9/+EvY7ZhXAsjHjC5rttyuXPXEDriJZKhzsg5d2iXw6V3KKfi7/sSlh2DT3nkruLQfMZkPoA4nf18rhyiCJttyOhjVZ+R5P/RBcevlocQfBGQmgztwZel0N4J1co7Msfujoya4ggI5/O2TfUmGo4ZbtzeO/lD3vMg0cbo1z72kxGjR/Z47GqWrcXNXNt0a/fEXnH7fSenOOw7PdVSOIACdc8uhsJbYIMvQoCY3HTLB6uav5n0PWQu8iZfAWWXwtLfgCBdbMfWkKQeK7cJ2BMn1z44Llsd8DWBMNBgqEA4zYezYyHfrpGEgfqNon3pn5XrWStMrga/TJTVKvSidyH5BsuBFWXoFPvQnA8tD3s+ot+eQbZ29MlXMOM9L/J3nIOt/XfmAGkeWgT0+86k654F4nOJM1Dm6odUk2p30Qe2Qfit5O7ZZsH4UmQeL6SUa2S/hi/4y8Qv9E1jlZcuYDAOuBtSPYkvkIS0h/jfryrv2EFILxNuaI2piiRWIRILEu3LtOrup1akeZTXUd7yba1PQTSiAz5WWbddW+/WB6EtqLw4lyF8mHp2W5krnEg7pYQpt6GxAMFPD+J284v7hylEaQZGXqtKz1gjBk06nZELt4wGP4AxO9Hk3OBZtB5kP4EQlsijccigVHQeim69EKIz2bVKHjFdIUHEkNaLkSX/AhSpV6nne3Tgk/vo/HVHwsEt3IdkaK7rNwBaowZPOo2kQOIRKHhEIRDenlMBGk5Dx3yM1SXQsds6LwP0ksgOBaCE9DOpyD1egUj76PkP6D9X6j/KcQORTybfzRmMKnrRN4XGr8f2qcDXqZGuQ/JRZB8Djf1MvDalfbgfwbtM9GOP0Lb3Yhn62+NGSzqdo68LzT5Fiz9mZuj1mW4xg5drNo2X+lVLf3VBel56PLfVzsQY0wJWSIvgHbcSuHz0gNdEjofrnYQxpgSskReCP8Lei2yVWu83F3OjTG1pySJXETOFBEVkeGlON5AI5Hda3ATjZC9RkwMaTgGTczBX3Qc/oK98JecjaY+qnSAxpgSKTqRi8hYYC/g4+LDGaBiB0JgAq5d3Aoe7lpxiIF5zdiD2HGu/6c0gDQBYWj4NqpBdNGxkHgS0h9B55/RhV9HU+9VO2hjTD+UIgNdBpwF9N42u4aJhKHtVrTjTuh8AKQJafwOeK3o0hmQfKnaIWaRhvgfYditiKQhvcA1n/Da0AU70bO+eRq0A22f6eq5GGNqSlGJXESmAp+q6iv5CtmIyDRgGsC4cYU1Zh1IRKIueTd+Z+X3NPlPSL5O7obIZY8KV4o316qZBCy/Bhl6xcqNp5r+AvxsHc4VEnPLE6YxpqzyJnIReQQYleWuc4GfAHsX8kKqOguYBa6MbR9iHLi6Hqeqq1mC60H0CFh2MdmTuULX3/A/39RVPYzuB02nk3PNu9eGJt9El18HqQ8hvPWqHa7GmAErbyJX1T2zfV9ENgMmACtG42OAuSKyjap+XtIoByqJ4P4Jq5DMw7tA60wgDMkXoStX/RXffWkS4vdA4iXXHanzPnom/xhEdsnUPE+456TeROOzoW02Eqy9T1HG1It+X+xU1ddUdaSqjlfV8cAnwFZ1k8QBovtTmu5BfT1GwE2PzN8W5m8J/gKI7Ev+wl1pSP8HortBdM/M4xuAKDROg84HcXPnK5ZapkCXoe2/7mN8xphKsnXkRZDAWjDkl8UfyMvRBCKnEKReYuVoO/kCdD0JsaMKeG4nJN9k1Y++E8JbQ3QK+AuzPN6HxLN9jM8YU0klWzeXGZXXHQm0ogTo/wVPDwKt4IfI3+xiOET3hs6bs9zXAV2F7NgUV8nR/2LV6yWehcXHkXvuvLC6LJp8G43fDdqBRPeG8I7WzcWYChiIC6BrS9GrVnxIziX/zlGB0HjovLWXQ31WwOsFwV9CzzcNH/w4BDdy9c67z/lLDBr+K+9R/eU3QftFrJhf184/Q3hnaL3CkrkxZWZTK0VQVdQbQc+NQv1RyPZ/heScPI/NtxjIA28ErujX6uIQ3BTC2wIRkGb339jhSMMRvUfmL4L2GfSYX9cOSDzlNh0ZY8rKRuT95HfcA8suzcwr10AdFmkA1V5G7Q1IeDOk4Xw0/SmkP4Pgeog3NP+xu54BCa7Z21Q70M4HkciUosM3xuRmI/J+0M6HYOnPwZ+Pm1ZR3MoTL/PVDAyw2izyFdwbTq5Rewe6dDr+ommgPhKeXFgSB9egOiuPAffvYMwgZIm8H7T9cnpucQeXIAO4JX3tZJ++qCL/A3LvAF0xh52CxJPowkNRf2nhx47sTPY3iDDS8M0+hWmM6TtL5P3hf5rjjiR5m0zIcAbeP3v3JOyDxt1GoAKJxJDWq7o1eW4AwtB0ChLarOTRGmN6sjny/gis2/8enZE9IPUypN4ne3PlSgqyci16D52Z1TiFk8j2MOIZSDzhVsBEdkICI0sVqDGmFwNtaFgTpPlM1lypEsIVsMoj/Q7e8L9A9LAyRNYXAQjvgOs3urooBDfu8xHFa0Ci+yEN37QkbkwFWSLvB4ns4Mq9BjcGIhAYD83nu8JU+QQ3dsv1Ou8od5i9ix6KDL0WguvT8w1IQCJIwyHViswY00c2tdJPEtkRifQswa6hcejiE0BTZL/Y6UHTqZmemdUqfZuJw2tyG3WG3YC2/xLi9wMpCG+DDDkP8VqrGJ8xpi8skZeQhCfDyGch8Ty6/HZI/LXnA6JHIroE9fNcEO23IIXNu4eRmFtNIl4T0nIROmSGu227MI2pOZbIS0wkDJGd0GVXskZi7bwR7bwj03atHPIl8QYgDc1nI6H1e9xjCdyY2mWJvAw09SEk/0n2xNqV2QFZ6Oi5RLwR0PRjJLoj4g2r3OsaY8rOEnk5+PPdhU9dfdPQ6iqYzJt/ihfbrzKvZYypKFu1Ug7BDUHzdQ1KUbkaLSEksnOFXssYU2mWyMtAvBZoPM6VgM35oAYIjKH8H4oCEJyMLjkV//OJ+PMm4S+9BM37RmOMqRWWyMtEmk5FWmZA6Gu4i4yBbveGwVsLhv4hsxa9gI1E/aaQegESTwMJ0KXQ8Sd0yWllfE1jTCUVlchF5Bci8qmIvJz52r9UgdU6EUGi++G13Yl8ZS40n+eSdmACNE5D2u7AC47GG34XtN0L3mhK0/9zdT6uBkz3eiqd0PUP/OS76OqlZ40xNacUn+svU9VLS3CcQUvEQxq/BY3fynq/F1oXf8g5sOSUCkaVgoUHoQga3gZp+RUSWLuCr2+MKRWbWqkC7XoWf+FR+PN3xl98App8EzpuJH+Hn1JK40brabeBaeHhNm9uTI0qRSI/WUReFZHrRaTATgT1y48/iC4+HpIvgD8Puh5DFx6RWXdejGJ+lGnQZdD1aJExGGOqIe9fv4g8IiKvZ/k6GLgKWBfYAvgPMLOX40wTkTkiMmfBggUlO4FaoqrQfgE9m1Iori5LkUsRA1viKhkG8j0yR3BxSH1UXAzGmKrIO0euqnsWciARuRa4r5fjzAJmAUyaNKmScwgDh7aDvzjHfSlcadzuST7mmiDr/PzH9sLQcgMsPtYl5b6SGIQ26vvzjDFVV+yqlbW63fwG0M9uC3VCYuR87wysBS2XgLc24Ll6LE3fh2CByTX1pmuCrIWO7Lv/6MMQGA1h2zRkTC0qdtXKxSKyBW5+4EPg+KIjGsREQmjDEdBxCz1G3hKDxhPwYvug0b1x7eLCiHj4wb/CkifzH9xrheSL5G01h4C3AYQnQtfD7nb0QKT5DET6OS1jjKmqohK5qh5dqkDqhTT/yK0Oid8JEgAEGn+AxL7u7hehe/ch0TRKCLcWvBeN09yoPPE8ueu3ZH7c/nvQNR8av4c0noCIldwxppbZX3CFiQSRlulo85ngL4TAKFf6NheNgwRBcyVyD0Lbu/ri6U/Q+J2Z+fYVwiDRTAGvbssLdTEsm4WmPkJaLynBmRljqsXWkVeJeI1IcFzvSRwgslOOee8ghHdFhl6HDLvebToKjkOGXu+aQxMEQhCenCnglW2NeCd0PoimPy/6fIwx1WOJfICTwChoOgk33ZL5cUkMInsiQ69BIjv1aAoh4a3xRjyIjHwO+cpcJLIHvW40kgik3i/nKRhjysymVmqA13QCGt4ejc8G7URi+0F4l167+ojXDIAGRmWmZnJcBNUEBNYpR9jGmAqxRF4jJLw5Et6870+MTAFpBO1gzZF5GCI7IMExpQjRGFMlNrUyyImEkGE3Q3BT3Pv2ilF8CGKHIK2XVzE6Y0wp2Ii8DkhwHDJ8NppeACRRaXMJXux93JjBwBJ5HZHACPffKsdhjCktG5IZY0yNs0RujDE1zqZW6pD6HWj8L5B6HYLrIrFvuIbRxpiaZIm8zmh6HrrwEPDbcXXQo+iy30HbbUjwq9UOzxjTDza1Ume0/SJX44UVNcs7QZeiX/60mmEZY4pgibzedP0d16+zO4XkXOvZaUyNskRed3LNpnnYr4Mxtcn+cutN7OvA6hUXgxDZ3eqSG1OjLJHXGWk6A0KbgDQAUVeHJbAO0nJ+tUMzxvSTDcHqjHgNMOw2SL4EqXdc5cPwtrZd35gaVnQiF5FTgJNx/cXuV9Wzio7KlJWIQHgr92WMqXlFJXIR2Q04GPiaqnaJyMjShGWMMaZQxX6ePhGYoeq6Fqjq/OJDMsYY0xfFJvINgJ1F5DkReUJEJud6oIhME5E5IjJnwYIFRb6sMcaYFfJOrYjII8CoLHedm3n+UGA7YDJwu4h8VVXXaBKpqrOAWQCTJk3qpYmkMcaYvsibyFV1z1z3iciJwOxM4n5eRHxgOGBDbmOMqZBiV63cA+wOPC4iG+B2mnyR70kvvvjiFyLyUZGvPdAMp4BzH2Tq8ZyhPs+7Hs8ZBt55Z+2ULllmQQomImHgemALIAGcqap/7/cBa5iIzFHVSdWOo5Lq8ZyhPs+7Hs8Zaue8ixqRq6uy9J0SxWKMMaYfbDufMcbUOEvkpTOr2gFUQT2eM9TnedfjOUONnHdRc+TGGGOqz0bkxhhT4yyRl4GInCkiKiLDqx1LuYnIJSLyloi8KiJ3i0hrtWMqFxHZV0TeFpH3ROTH1Y6nEkRkrIg8JiJvisgbInJatWOqFBEJiMhLInJftWPJxxJ5iYnIWGAv4ONqx1IhDwMTVfVrwDvAOVWOpyxEJAD8DtgP2AT4tohsUt2oKiIF/FBVN8bt4D6pTs4b4DTgzWoHUQhL5KV3GXAWUBcXH1T1b6qaytz8P2BMNeMpo22A91T1X5llt7fiKn8Oaqr6H1Wdm/n/dlxiG13dqMpPRMYABwDXVTuWQlgiLyERmQp8qqqvVDuWKjkWeLDaQZTJaODf3W5/Qh0ktO5EZDywJfBcdSOpiN/gBmR+tQMphHUI6qM8RcR+Auxd2YjKr7dzVtV7M485F/cx/KZKxlZBkuV7dfGpC0BEmoC7gNNVdWm14yknETkQmK+qL4rIrtWOpxCWyPsoVxExEdkMmAC8IiLgphjmisg2qvp5BUMsud4KpwGIyHeBA4E9slW+HCQ+AcZ2uz0G+KxKsVSUiIRwSfwmVZ1d7XgqYEdgqojsD0SBISJyo6oO2F3sto68TETkQ2CSqg6kgjslJyL7Ar8GpqjqoK16KSJB3MXcPYBPgReAI1X1jaoGVmbiRiV/ABap6unVjqfSMiPyM1X1wGrH0hubIzfFuhJoBh4WkZdF5OpqB1QOmQu6JwMP4S743T7Yk3jGjsDRwO6Zn+/LmZGqGUBsRG6MMTXORuTGGFPjLJEbY0yNs0RujDE1zhK5McbUOEvkxhhT4yyRG2NMjbNEbowxNc4SuTHG1Lj/BwijQn9Pc6xEAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "classes, points = generate_data(1000)\n",
    "one_hot_classes = dc.metrics.to_one_hot(classes, n_classes)\n",
    "gen_points = gan.predict_gan_generator(conditional_inputs=[one_hot_classes])\n",
    "plot.scatter(x=gen_points[:,0], y=gen_points[:,1], c=classes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "StyDTNfRqSV8"
   },
   "source": [
    "# Congratulations! Time to join the Community!\n",
    "\n",
    "Congratulations on completing this tutorial notebook! If you enjoyed working through the tutorial, and want to continue working with DeepChem, we encourage you to finish the rest of the tutorials in this series. You can also help the DeepChem community in the following ways:\n",
    "\n",
    "## Star DeepChem on [GitHub](https://github.com/deepchem/deepchem)\n",
    "This helps build awareness of the DeepChem project and the tools for open source drug discovery that we're trying to build.\n",
    "\n",
    "## Join the DeepChem Gitter\n",
    "The DeepChem [Gitter](https://gitter.im/deepchem/Lobby) hosts a number of scientists, developers, and enthusiasts interested in deep learning for the life sciences. Join the conversation!"
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "name": "16_Conditional_Generative_Adversarial_Networks.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
